package com.w08e.waai.service;

import com.w08e.waai.SendGroupMessage;
import com.w08e.waai.dto.TradingStrategyResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 交易策略定时任务服务
 * @Author: 智能交易策略系统
 * @Date: 2025/1/14
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TradingScheduledService {
    
    private final BinanceDataService binanceDataService;
    private final AiStrategyService aiStrategyService;
    
    // 钉钉群配置（从application.yaml读取或使用默认值）
    @Value("${dingtalk.conversation-id:cidWkB3dR7UvwY0oScabFsctg==}")
    private String conversationId;
    
    @Value("${dingtalk.robot-code:dingdccijs9wyugmlyfc}")
    private String robotCode;
    
    @Value("${trading.symbol:ETHUSDT}")
    private String tradingSymbol;
    
    /**
     * 每30分钟执行一次交易策略分析
     * cron表达式：秒 分 时 日 月 周
     * "0 0/30 * * * ?" 表示每30分钟的第0秒执行
     */
    @Scheduled(cron = "0 0/30 * * * ?")
    public void executeTradingStrategyAnalysis() {
        log.info("=== 开始执行定时交易策略分析 ===");
        LocalDateTime startTime = LocalDateTime.now();
        
        try {
            // 1. 获取最新K线数据
            log.info("步骤1: 获取 {} 最新K线数据...", tradingSymbol);
            String klineData = binanceDataService.getLatest24HourKlineData(tradingSymbol);
            
            if (klineData == null || klineData.isEmpty()) {
                String errorMsg = "获取K线数据失败，跳过本次分析";
                log.error(errorMsg);
                sendErrorNotification(errorMsg);
                return;
            }
            
            log.info("步骤1完成: 成功获取K线数据，长度: {} 字符", klineData.length());
            
            // 2. 调用AI生成交易策略
            log.info("步骤2: 调用AI生成交易策略...");
            TradingStrategyResponse strategy = aiStrategyService.generateTradingStrategy(tradingSymbol, klineData);
            
            if (strategy == null) {
                String errorMsg = "AI策略生成失败，返回null";
                log.error(errorMsg);
                sendErrorNotification(errorMsg);
                return;
            }
            
            log.info("步骤2完成: 成功生成AI交易策略");
            
            // 3. 发送钉钉消息
            log.info("步骤3: 发送交易策略到钉钉群...");
            sendTradingStrategyToDingTalk(strategy);
            log.info("步骤3完成: 钉钉消息发送完成");
            
            // 记录执行结果
            LocalDateTime endTime = LocalDateTime.now();
            long executionTime = java.time.Duration.between(startTime, endTime).toMillis();
            log.info("=== 定时交易策略分析执行完成 ===");
            log.info("总耗时: {} ms", executionTime);
            log.info("策略方向: 短期[{}] 长期[{}]", 
                    getDirectionSafe(strategy.getShortTermStrategy()),
                    getDirectionSafe(strategy.getLongTermStrategy()));
            
        } catch (Exception e) {
            log.error("定时交易策略分析执行异常", e);
            sendErrorNotification("定时任务执行异常: " + e.getMessage());
        }
    }
    
    /**
     * 发送交易策略到钉钉群
     */
    private void sendTradingStrategyToDingTalk(TradingStrategyResponse strategy) {
        try {
            String formattedMessage = strategy.formatForDingMessage();
            
            // 添加执行时间信息
            String timeInfo = "\n⏰ 执行时间: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String finalMessage = formattedMessage + timeInfo;
            
            log.info("准备发送钉钉消息，长度: {} 字符", finalMessage.length());
            log.debug("钉钉消息内容预览:\n{}", finalMessage.substring(0, Math.min(200, finalMessage.length())));
            
            // 调用钉钉发送方法
            SendGroupMessage.sendActiveGroupMessage(conversationId, robotCode, finalMessage);
            
            log.info("交易策略钉钉消息发送成功");
            
        } catch (Exception e) {
            log.error("发送交易策略钉钉消息失败", e);
            // 发送错误通知
            sendErrorNotification("钉钉消息发送失败: " + e.getMessage());
        }
    }
    
    /**
     * 发送错误通知到钉钉群
     */
    private void sendErrorNotification(String errorMessage) {
        try {
            String message = String.format("""
                🚨 交易策略系统异常 🚨
                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                ⏰ 时间: %s
                ❌ 错误: %s
                📋 交易对: %s
                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                🔧 请检查系统状态并及时处理
                """, 
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                errorMessage,
                tradingSymbol
            );
            
            SendGroupMessage.sendActiveGroupMessage(conversationId, robotCode, message);
            log.info("错误通知已发送到钉钉群");
            
        } catch (Exception e) {
            log.error("发送错误通知失败", e);
        }
    }
    
    /**
     * 安全获取策略方向
     */
    private String getDirectionSafe(TradingStrategyResponse.ShortTermStrategy strategy) {
        return strategy != null ? strategy.getDirection() : "未知";
    }
    
    /**
     * 安全获取策略方向
     */
    private String getDirectionSafe(TradingStrategyResponse.LongTermStrategy strategy) {
        return strategy != null ? strategy.getDirection() : "未知";
    }
    
    /**
     * 手动触发策略分析（用于测试）
     */
    public TradingStrategyResponse manualTriggerAnalysis() {
        log.info("手动触发交易策略分析");
        
        try {
            String klineData = binanceDataService.getLatest24HourKlineData(tradingSymbol);
            if (klineData == null || klineData.isEmpty()) {
                throw new RuntimeException("获取K线数据失败");
            }
            
            TradingStrategyResponse strategy = aiStrategyService.generateTradingStrategy(tradingSymbol, klineData);
            if (strategy == null) {
                throw new RuntimeException("AI策略生成失败");
            }
            
            log.info("手动分析完成");
            return strategy;
            
        } catch (Exception e) {
            log.error("手动触发分析失败", e);
            throw new RuntimeException("手动分析失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 发送测试消息到钉钉群
     */
    public void sendTestMessage() {
        try {
            String testMessage = String.format("""
                🧪 交易策略系统测试消息
                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                ⏰ 测试时间: %s
                📊 交易对: %s
                🤖 系统状态: 正常运行
                ⚙️ 定时任务: 每30分钟执行
                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                ✅ 如果收到此消息，说明钉钉推送功能正常
                """,
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                tradingSymbol
            );
            
            SendGroupMessage.sendActiveGroupMessage(conversationId, robotCode, testMessage);
            log.info("测试消息发送成功");
            
        } catch (Exception e) {
            log.error("发送测试消息失败", e);
            throw new RuntimeException("测试消息发送失败: " + e.getMessage(), e);
        }
    }
} 